use mlua::Lua;
use std::sync::Arc;
use crate::core::monitor::LuaMemoryTracker;

pub async fn setup_lua_apis(
    lua: &Lua,
    memory_tracker: Arc<LuaMemoryTracker>,
    worker_id: u64,
) -> mlua::Result<()> {
    let globals = lua.globals();

    // 内存追踪设置
    lua.set_memory_limit(memory_tracker.get_limit())?;
    lua.set_gc_step_kb(1024)?; // 控制GC频率

    // 系统操作API
    let sys_ops = lua.create_table()?;
    sys_ops.set("get_memory_usage", lua.create_function(|_, ()| {
        Ok(get_system_memory_usage())
    })?)?;
    
    sys_ops.set("get_cpu_usage", lua.create_function(|_, ()| {
        Ok(get_cpu_usage())
    })?)?;
    
    sys_ops.set("log", lua.create_function(|_, (level, message): (String, String)| {
        log_message(&level, &message);
        Ok(())
    })?)?;
    
    globals.set("sys", sys_ops)?;

    // HTTP客户端API
    let http_client = lua.create_table()?;
    http_client.set("get", lua.create_async_function(|lua, url: String| async move {
        let result = make_http_request("GET", &url, None).await?;
        lua.to_value(&result)
    })?)?;
    
    http_client.set("post", lua.create_async_function(|lua, (url, body): (String, String)| async move {
        let result = make_http_request("POST", &url, Some(body)).await?;
        lua.to_value(&result)
    })?)?;
    
    globals.set("http", http_client)?;

    // 内存状态API
    let mem_api = lua.create_table()?;
    let tracker_ref = Arc::downgrade(&memory_tracker);
    let worker_id_ref = worker_id;
    
    mem_api.set("current", lua.create_function(move |_, ()| {
        if let Some(tracker) = tracker_ref.upgrade() {
            Ok(tracker.get_memory_usage(worker_id_ref) as usize)
        } else {
            Ok(0)
        }
    })?)?;
    
    mem_api.set("limit", lua.create_function(move |_, ()| {
        if let Some(tracker) = tracker_ref.upgrade() {
            Ok(tracker.get_limit() as usize)
        } else {
            Ok(0)
        }
    })?)?;
    
    globals.set("memory", mem_api)?;

    Ok(())
}

fn get_system_memory_usage() -> f64 {
    let mut system = sysinfo::System::new();
    system.refresh_memory();
    system.used_memory() as f64 / 1024.0 / 1024.0 // MB
}

fn get_cpu_usage() -> f64 {
    let mut system = sysinfo::System::new();
    system.refresh_cpu();
    system.global_cpu_usage() as f64
}

fn log_message(level: &str, message: &str) {
    match level.to_lowercase().as_str() {
        "error" => tracing::error!(%message),
        "warn" => tracing::warn!(%message),
        "info" => tracing::info!(%message),
        "debug" => tracing::debug!(%message),
        _ => tracing::info!(level, %message),
    }
}

async fn make_http_request(method: &str, url: &str, body: Option<String>) -> anyhow::Result<String> {
    let client = reqwest::Client::new();
    let response = match method {
        "GET" => client.get(url).send().await?,
        "POST" => client.post(url).body(body.unwrap_or_default()).send().await?,
        _ => return Err(anyhow::anyhow!("Unsupported HTTP method")),
    };
    
    if response.status().is_success() {
        Ok(response.text().await?)
    } else {
        Err(anyhow::anyhow!("HTTP error: {}", response.status()))
    }
}